﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MathLab.Utils
{
  class Matrix
  {
    public string name { get; set; }
    public double[,] matrix {get; set;}
    /// <summary>
    /// Creating a new instance of class Matrix
    /// </summary>
    /// <param name="sName">name of matrix</param>
    /// <param name="dMatrix">two-dimension array</param>
    public Matrix(string sName, double[,] dMatrix)
    {
      this.name = sName;
      this.matrix = dMatrix;
    }

    public Matrix()
    {
    }

    public static Matrix operator +(Matrix matrixA, Matrix matrixB)
    {
      return new Matrix(matrixA.name + "+" + matrixB.name, MatrixSum.Sum(matrixA.matrix, matrixB.matrix));
    }

    //multiplying
    public static Matrix operator *(Matrix matrixA, Matrix matrixB)
    {
      return new Matrix(matrixA.name + "*" + matrixB.name, MatrixMultiply.Multiply(matrixA.matrix, matrixB.matrix));
    }

    public static Matrix operator *(Vector vector, Matrix matrix)
    {
      return new Matrix(vector.name + "*" + matrix.name, MatrixMultiply.Multiply(vector.vector, matrix.matrix));
    }

    public static Matrix operator *(Matrix matrix, Vector vector)
    {
      return new Matrix(matrix.name + "*" + vector.name, MatrixMultiply.Multiply(vector.vector, matrix.matrix));
    }

    //scalar multiplying
    public static Matrix operator *(Matrix matrix, double factor)
    {
      return new Matrix(matrix.name + "*" + factor.ToString(), MatrixFactorMultiply.FactorMultiply(matrix.matrix, factor));
    }

    public static Matrix operator *(double factor, Matrix matrix)
    {
      return new Matrix(factor.ToString() + "*" + matrix.name, MatrixFactorMultiply.FactorMultiply(matrix.matrix, factor));
    }

    public static Matrix operator |(Matrix matrixA, Matrix matrixB)
    {
        Vector vectorA = new Vector();
        Vector vectorB = new Vector();
        
        if (
            (matrixA.matrix.GetUpperBound(0) == 2) &&
            (matrixA.matrix.GetUpperBound(1) == 0) &&
            (matrixB.matrix.GetUpperBound(0) == 2) &&
            (matrixB.matrix.GetUpperBound(1) == 0)
            )
        {
            vectorA.vector = new double[3];
            vectorB.vector = new double[3];
            for (int i = 0; i < 3; i++)
            {
                vectorA.vector[i] = matrixA.matrix[i, 0];
                vectorB.vector[i] = matrixB.matrix[i, 0];
            }
        }

        Matrix result = new Matrix();
        result.name = vectorA.name + "|" + vectorB.name;
        result.matrix = new double[1, 3];

        Vector vector = new Vector(vectorA.name + "|" + vectorB.name, VectorMultiply.ScalarMultiplyVector(vectorA.vector, vectorB.vector));

        for (int i = 0; i < 3; i++)
        {
            result.matrix[0, i] = vector.vector[i];
        }

        return result;
    }

  }
}
